#include <fstream>
#include <list>
#include <iterator>

using namespace std;

class widget{
	/* 假定它有一个默认的构造函数 */
};

int main()
{
#if 1
	ifstream dataFile("ints.dat");

	// 这里并不会读入任何数据，甚至不会创建一个list对象.
	// 这个语句并没有创建一个list也没有调用一个构造函数,
	// 那它到底干嘛了呢?
	//
	// 这个语句声明了一个函数data,其返回类型为list<int>.
	// 它带有2个参数:第一个为dataFile,其类型为istream_iterator<int>,
	// 包含dataFile的括号被编译器忽略(因为这对括号中有
	// 参数).第二个参数没有参数名,其类型为一个函数指针(
	// 由于那对空的括号,编译器认为这里是一个函数指针),
	// 该指针指向的函数返回一个istream_iterator<int>类型
	// 的返回值.
	list<int> data(istream_iterator<int>(dataFile), istream_iterator<int>());
#else	
	////////////////////////////////////////////////////////////////////////

	// It's not legal to surround a formal parameter declaration with
	// parentheses, but it is legal to surround an argument to a function
	// call with parentheses.
	// 
	// 要达到上面原来的效果,可以将第一个参数用括号括起来,这样
	// 编译器就会按照作者的本意来识别代码了!
	// 
	// Unfortunately, not all compilers currently know it themselves. Of
	// the several I tested, almost half refused to accept data's declaration
	// unless it was INCORRECTLY declared without the additional parentheses!
	// To placate such compilers, you could roll your eyes and use the declaration
	// for data that I've painstakingly explained is incorrect, but that
	// would be both unportable and short-sighted. After all, compilers
	// that currently get the parse wrong will surely correct it in the
	// future, right?  */
	
	list<int> data((istream_iterator<int>(dataFile)), istream_iterator<int>());
	
	////////////////////////////////////////////////////////////////////////

	// 最好的方式就是分离这个语句,下面的语句跑到哪都能正确运行
	//
	// This use of named iterator objects runs contrary to common STL
	// programming style, but you may decide that's a price worth paying
	// for code that is unambiguous to both compilers and the humans
	// who have to work with them!

	istream dataFile("inst.dat");
	istream_iterator<int> dataBegin(dataFile);
	istream_iterator<int> dataEnd;
	list<int> data(dataBegin, dataEnd);

	////////////////////////////////////////////////////////////////////////
	
	// 这是声明一个函数还是定一个一个对象?
	// 实际上这里声明了一个函数,其返回类型为widget,它没有带任何参数.
	widget w();
#endif

	return 0;
}
